
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>5-MySQL_JDBC - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>5-MySQL_JDBC - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是JDBC？它与数据库驱动程序之间是什么关系？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JDBC (Java Database Connectivity) 是SUN公司提供的一套用于操作数据库的标准规范。JDBC与数据库驱动的关系是接口与实现的关系。</div>
          </div>
          <div class="card-source">来源: JDBC</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">JDBC中的“四大金刚”指的是哪四个核心组件，它们各自的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JDBC的四大核心组件是：1. DriverManager：用于注册驱动；2. Connection：表示与数据库创建的连接对象；3. Statement：操作数据库SQL语句的对象；4. ResultSet：SQL语句执行后返回的结果集。</div>
          </div>
          <div class="card-source">来源: JDBC的四大金刚</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请简述使用JDBC操作数据库的基本步骤。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">使用JDBC操作数据库的基本步骤包括：1. 加载驱动；2. 创建连接对象；3. 创建Statement对象；4. 通过Statement对象执行SQL语句；5. 获取执行结果。</div>
          </div>
          <div class="card-source">来源: JDBC操作步骤</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">文档中提到的SQL注入问题是什么？推荐的解决方案是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">SQL注入问题是指通过拼接SQL字符串的方式，恶意用户可以构造特殊的输入来绕过验证或执行恶意SQL命令。文档推荐的解决方案是采用预编译对象（例如 PreparedStatement）来编程。</div>
          </div>
          <div class="card-source">来源: SQL注入问题</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">请解释MVC设计思想中M、V、C三层的职责。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">MVC是一种架构模式，将应用分为三层：模型层(M)负责业务数据的信息表示；视图层(V)为用户提供页面展示，关注数据的展现；控制器(C)负责接受用户请求，并调用相应的模型进行处理。</div>
          </div>
          <div class="card-source">来源: MVC设计思想</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在JDBC中，如何调用一个带有OUT参数的存储过程？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">首先使用 `connection.prepareCall("{call procedure_name(?,?)}")` 创建一个 `CallableStatement` 对象。然后，除了设置IN参数外，还需要使用 `registerOutParameter(parameterIndex, Types.VARCHAR)` 等方法注册OUT参数。执行存储过程后，通过 `getString(parameterIndex)` 等方法获取OUT参数的值。</div>
          </div>
          <div class="card-source">来源: Java中调用参数中有OUT的</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">实践</div>
          <div class="card-question">在JDBC编程中，为什么强调要正确关闭资源？通常采用什么方式来确保资源被关闭？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">实践</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">为了防止资源泄露，JDBC编程中必须正确关闭资源（如Connection, Statement, ResultSet）。通常的做法是在 `finally` 代码块中执行关闭操作，以确保即使在发生异常时也能成功关闭资源。</div>
          </div>
          <div class="card-source">来源: 资源的正确关闭</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在MyBatis中如何调用一个存储过程？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在MyBatis的Mapper XML文件中，可以通过将 `statementType` 属性设置为 `"CALLABLE"` 来调用存储过程。例如：`<insert id="empmAdd" statementType="CALLABLE">{call p_emp_add(#{ename},#{job},#{mgr})}</insert>`。</div>
          </div>
          <div class="card-source">来源: MyBatis调用储存过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">实践</div>
          <div class="card-question">在为JDBC创建工具类时，对于连接数据库所需的可变信息（如URL、用户名、密码），推荐的处理方式是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">实践</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">推荐将这些变化的信息配置到外部的配置文件中，而不是在代码中硬编码。工具类从配置文件中读取这些信息来创建数据库连接。</div>
          </div>
          <div class="card-source">来源: 创建工具类</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
